<template>
  <div class="register-form" @mouseenter="isHover = true" @mouseleave="isHover = false">
    <div class="register-form-container">
      <div class="register-form-wrapper" v-if="isRender">
        <div class="register-form-title mb-3">{{ modelValue?.data?.title }}</div>
        <div class="row mb-6">
          <div class="col col-12 col-md-6">
            <FormInput
              ref="field1"
              class="mb-0"
              componentKey="name"
              title="姓名"
              placeholder="你的名字"
              :value="result.name"
              @updateValue="updateResultValue('name', $event)"
              @updateError="updateErrorFromInput"
            />
          </div>
          <div class="col col-12 col-md-6">
            <FormSelect
              ref="field2"
              class="mb-0"
              componentKey="youare"
              title="你是"
              :options="optionsYouare"
              placeholder="Select"
              :value="result.youare"
              @updateValue="updateResultValue('youare', $event)"
              @updateError="updateErrorFromInput"
            />
          </div>
          <div
            v-show="formSubmitFormat.person_type == 'others'"
            class="other-col-temp col col-12 col-md-6"
          ></div>
          <div
            v-show="formSubmitFormat.person_type == 'others'"
            class="col col-12 col-md-6"
          >
            <input
              type="text"
              class="default-input"
              v-model="result.other_person_type"
              placeholder="其他"
            />
          </div>
          <div class="col col-12 col-md-6">
            <FormPhone
              ref="field3"
              class="mb-0"
              componentKey="number"
              title="联系电话"
              :value="result.number"
              :error="{ errorMsg: '此为必填项' }"
              :website="website"
              :locale="locale"
              @updateValue="updateResultValue('number', $event)"
              @updateError="updateErrorFromInput"
            />
          </div>
          <div class="col col-12 col-md-6">
            <FormEmail
              ref="field4"
              class="mb-0"
              componentKey="email"
              title="电邮"
              placeholder="example@yourmail.com"
              :value="result.email"
              @updateValue="updateResultValue('email', $event)"
              @updateError="updateErrorFromInput"
            />
          </div>
          <div class="col col-12">
            <FormInput
              ref="field5"
              class="mb-0"
              componentKey="school_or_organisation_name"
              title="学校名称/组织"
              placeholder="学校名称/组织"
              :value="result.school_or_organisation_name"
              @updateValue="updateResultValue('school_or_organisation_name', $event)"
              @updateError="updateErrorFromInput"
            />
          </div>
        </div>
        <div class="register-form-btn mb-6">
          <BtnSubmit
            text="提交"
            @click="submitHandler"
            :isLoading="isLoading"
            :isSuccess="isSuccess"
            :isFail="isFail"
          />
        </div>
        <div>
          <input
            type="checkbox"
            class="default-checkbox"
            :id="`register-form-checkbox`"
            v-model="result.opt_out_direct_marketing"
          />
          <label
            :for="`register-form-checkbox`"
            v-html="modelValue?.data?.checkText"
          ></label>
        </div>
        <div
          class="register-form-notice mt-3"
          v-show="modelValue?.data?.notice"
        >{{ modelValue?.data?.notice }}</div>
      </div>
    </div>

    <Operate v-if="!isPreview" v-model:show="isHover" @handle-edit="showSetting = true" @handle-delete="handleDelete" @handle-copy="handleCopy" @handle-paste="handlePaste"></Operate>
  </div>

  <Setting v-if="!isPreview" v-model:show="showSetting" :data="modelValue"></Setting>
</template>

<script lang="ts" setup>
import { ref, computed, nextTick } from 'vue'
import { randomString } from '@/utils/common'
import Setting from './setting.vue'
import Operate from '@/common/Operate/index.vue'
import FormInput from '@/common/FormInput/index.vue'
import FormSelect from '@/common/FormSelect/index.vue'
import FormPhone from '@/common/FormPhone/index.vue'
import FormEmail from '@/common/FormEmail/index.vue'
import BtnSubmit from '@/common/BtnSubmit/index.vue'
import { http } from '@/utils/http'

// 定义组件名称
defineOptions({
  name: 'RegisterForm'
})

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  },
  isPreview: {
    type: Boolean,
    default: true
  },
  website: {
    type: String,
    default: 'ywies-tx'
  },
  locale: {
    type: String,
    default: 'sc'
  }
})

const emit = defineEmits(['update:modelValue', 'handleDelete', 'handleCopy', 'handlePaste', 'handleClick'])

const handleInit = () => {
  if (props.modelValue && props.modelValue.data) return // 有数据不用初始化
  const data = {
    id: props.modelValue?.id || randomString(),
    type: 'RegisterForm',
    data: {
      title: '注册表单',
      event_name: '12',
      checkText: '我同意接收来自官方的直接营销信息',
      notice: '注意：请勿在表单中填写任何个人身份信息，如身份证号、护照号等。',
    },
    api: props.modelValue?.api || '/submit-form/event-registration'
  }
  emit('update:modelValue', data)
} 

const isHover = ref<boolean>(false);
const showSetting = ref<boolean>(false);

const handleDelete = () => {
  emit('handleDelete', props.modelValue.id)
}

const handleCopy = () => {
  emit('handleCopy', props.modelValue)
}

const handlePaste = (type: string) => {
  emit('handlePaste', type)
}

handleInit()

interface FormResult {
  name: string[]
  youare: string
  other_person_type: string
  number: any
  email: string
  school_or_organisation_name: string[]
  opt_out_direct_marketing: boolean
}

const result = ref<FormResult>({
  name: [],
  youare: '',
  other_person_type: '',
  number: null,
  email: '',
  school_or_organisation_name: [],
  opt_out_direct_marketing: false
})

const error = ref<string[]>([])
const isRender = ref(true)
const isLoading = ref(false)
const isSuccess = ref(false)
const isFail = ref(false)

const field1 = ref(null)
const field2 = ref(null)
const field3 = ref(null)
const field4 = ref(null)
const field5 = ref(null)

const event_date = computed(() => {
  return props.componentProps?.event_date ?? ''
})

const optionsYouare = computed(() => {
  return props.componentProps?.optionsYouare ?? [
    {
      key: 'parent',
      name: '家长',
      value: '家长'
    },
    {
      key: 'alumni',
      name: '校友',
      value: '校友'
    },
    {
      key: 'student',
      name: '学生',
      value: '学生'
    },
    {
      key: 'faculty-staff',
      name: '教学人员/行政人员',
      value: '教学人员/行政人员'
    },
    {
      key: 'others',
      name: '其他',
      value: '其他'
    }
  ]
})

const formSubmitFormat = computed(() => {
  const obj: Record<string, any> = {
    event_code: props.modelValue?.event_name,
    name: result.value.name?.join(' '),
    person_type: optionsYouare.value.find((v: any) => v.value === result.value.youare)?.key,
    other_person_type: result.value.other_person_type,
    contact_number: result.value.number ? `+${result.value.number.code}${result.value.number.number}` : '',
    email: result.value.email,
    school_or_organisation_name: result.value.school_or_organisation_name?.join(','),
    opt_out_direct_marketing: +result.value.opt_out_direct_marketing,
    event_date: event_date.value
  }
  Object.keys(obj).forEach((key) => {
    if (!obj[key]) {
      delete obj[key]
    }
  })
  return obj
})

const updateResultValue = (key: string, value: any) => {
  result.value[key as keyof FormResult] = value
}

const updateErrorFromInput = ({ key, isPass }: { key: string; isPass: boolean }) => {
  if (!isPass && error.value.indexOf(key) < 0) {
    error.value.push(key)
  }
  if (isPass && error.value.indexOf(key) > -1) {
    error.value.splice(error.value.indexOf(key), 1)
  }
}

const submitHandler = () => {
  if (isLoading.value || isSuccess.value || isFail.value) return
  const fields = [field1.value, field2.value, field3.value, field4.value, field5.value]
  fields.forEach((v) => {
    v?.checkError?.()
  })
  nextTick(() => {
    if (error.value.length > 0) return
    submit()
  })
}

const submit = async () => {
  isLoading.value = true
  const params = JSON.stringify(formSubmitFormat.value)
  try {
    console.log('Submit form:', params)
    const { data } = await http.post(
      props.modelValue?.api,
      params,
      {
        headers: {
          website: `${props?.website}-${props?.locale}`,
        },
      }
    );
    const ref_no = data.data.ref_no;
    resetForm();
    emit('handleClick', `/thank-you?ref=${ref_no}`)
  } catch (e) {
    console.log(e)
    submitFail()
  } finally {
    isLoading.value = false
  }
}

const resetForm = () => {
  result.value = {
    name: [],
    youare: '',
    other_person_type: '',
    number: null,
    email: '',
    school_or_organisation_name: [],
    opt_out_direct_marketing: false
  }
  isLoading.value = false
  isSuccess.value = true
  setTimeout(() => {
    isSuccess.value = false
    reRender()
  }, 2500)
}

const submitFail = () => {
  isLoading.value = false
  isFail.value = true
  setTimeout(() => {
    isFail.value = false
  }, 3500)
}

const reRender = () => {
  isRender.value = false
  nextTick(() => {
    isRender.value = true
  })
}
</script>

<style lang="scss" scoped>
.mb-3 {
  margin-bottom: 12px!important
}
.mb-6 {
  margin-bottom: 24px!important
}

.row {
  --bs-gutter-x: 16px;
  --bs-gutter-y: 0;
  display: flex;
  flex-wrap: wrap;
  margin-top: calc(var(--bs-gutter-y)*-1);
  margin-right: calc(var(--bs-gutter-x)*-0.5);
  margin-left: calc(var(--bs-gutter-x)*-0.5)
}

.row>* {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  padding-right: calc(var(--bs-gutter-x)*0.5);
  padding-left: calc(var(--bs-gutter-x)*0.5);
  margin-top: var(--bs-gutter-y)
}

.col {
  flex: 1 0 0%
}

.col-12 {
  flex: 0 0 auto;
  width: 100%
}

.col-md-6 {
  @media (min-width: 768px) {
    flex: 0 0 auto;
    width: 50%
  }
}

input.default-input,textarea.default-textarea {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.75;
  color: #1a1c20;
  background: none;
  background: #f7f7fa;
  border-radius: 4px;
  border: none;
  padding: 8px 12px;
  outline: none;
  width: 100%
}

@media(max-width: 1023.98px) {
  input.default-input,textarea.default-textarea {
      font-size:14px;
      line-height: 1.714;
      letter-spacing: .01em
  }
}

@media(max-width: 767.98px) {
  input.default-input,textarea.default-textarea {
      background:#fff
  }
}

input.default-input:focus,textarea.default-textarea:focus {
  padding: 7px 11px;
  border: 1px solid #0048e8
}

input.default-input::-moz-placeholder,textarea.default-textarea::-moz-placeholder {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.75;
  color: #c0c0c4
}

input.default-input:-ms-input-placeholder,textarea.default-textarea:-ms-input-placeholder {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.75;
  color: #c0c0c4
}

input.default-input::placeholder,textarea.default-textarea::placeholder {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.75;
  color: #c0c0c4
}

@media(max-width: 1023.98px) {
  input.default-input::-moz-placeholder,textarea.default-textarea::-moz-placeholder {
      font-size:14px;
      line-height: 1.714;
      letter-spacing: .01em
  }

  input.default-input:-ms-input-placeholder,textarea.default-textarea:-ms-input-placeholder {
      font-size: 14px;
      line-height: 1.714;
      letter-spacing: .01em
  }

  input.default-input::placeholder,textarea.default-textarea::placeholder {
      font-size: 14px;
      line-height: 1.714;
      letter-spacing: .01em
  }
}

input.default-input.has-error,textarea.default-textarea.has-error {
  padding: 6px 10px;
  border: 2px solid #f04
}

input.default-input.has-error+.input-error,textarea.default-textarea.has-error+.input-error {
  opacity: 1;
  position: relative
}

input.default-input+.input-error,textarea.default-textarea+.input-error {
  position: absolute;
  margin-top: 4px;
  color: #ce031a;
  opacity: 0;
  transition: opacity .15s ease-in-out;
  pointer-events: none
}

.mb-0 {
  margin-bottom: 0!important
}

input.default-checkbox {
  display: none
}

input.default-checkbox:checked+label:before {
  background: #0032a0 50%/55% 42% no-repeat url()
}

input.default-checkbox+label {
  display: flex;
  cursor: pointer;
  margin-bottom: 8px
}

input.default-checkbox+label:before {
  content: "";
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-right: 12px;
  border-radius: 2px;
  background-color: #f7f7fa;
  transform: translateY(5px);
  transition: background-color .25s ease-out
}

@media(max-width: 767.98px) {
  input.default-checkbox+label:before {
    width:14px;
    height: 14px;
    margin-right: 8px;
    transform: translateY(4px);
    background-color: #fff
  }
}

.tx-body-small {
  font-size: 14px;
  font-weight: 400;
  line-height: 1.428;
}
@media (max-width: 1023.98px) {
  .tx-body-small {
    line-height: 1.285;
    letter-spacing: 0.03em;
    font-weight: 400;
  }
}

@media (max-width: 767.98px) {
  .tx-body-small {
    font-size: 13px;
    line-height: 1.33;
    letter-spacing: 0.02em;
  }
}

.register-form {
  position: relative;
}

.register-form-wrapper {
  background: #fff;
  padding: 60px;

  @media (max-width: 767.98px) {
    padding: 12px 0;
    background: #f7f7fa;
  }
}

.register-form-wrapper .row {
  --bs-gutter-x: 8px;
  --bs-gutter-y: 24px;
}

.register-form-title {
  font-size: 26px;
  line-height: 1.69;
  color: var(--text-color--primary, #0032a0);
  font-weight: 500;

  @media (max-width: 1023.98px) {
    font-size: 24px;
    line-height: 1;
  }

  @media (max-width: 767.98px) {
    font-size: 20px;
    line-height: 1.4;
  }
}

.register-form label {
  @extend .tx-body-small;
  color: #1A1C20;
}

.register-form label::before {
  transform: translateY(1px) !important;
}

.register-form-notice {
  font-size: 12px;
  font-weight: 500;
  color: #64788f;
}

.other-col-temp {
  @media (max-width: 767.98px) {
    display: none;
  }
}
</style>
